﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;

using log4net;
using log4net.Config;

namespace HouseOfCards
{
	/// <summary>
	/// Object that represents a poker hand
	/// </summary>
	public class Hand
	{
      private static readonly ILog _logger = LogManager.GetLogger("videopoker");

      /// <summary>
      /// Create a new Hand object for the current game type
      /// </summary>
      /// <param name="gameType"></param>
      public Hand(GameTypes gameType)
      {
         _gameType = gameType;
      }

      /// <summary>
      /// Number of cards in the hand
      /// </summary>
		public int CardCount
		{
			get
			{
				int cnt = 0;

				if (_card1 != null) cnt++;
				if (_card2 != null) cnt++;
				if (_card3 != null) cnt++;
				if (_card4 != null) cnt++;
				if (_card5 != null) cnt++;

				return cnt;
			}
		}
		private Card _card1;

      /// <summary>
      /// First card in the hand
      /// </summary>
		public Card Card1
		{
			get { return _card1; }
			set { _card1 = value; }
		}
		private Card _card2;

      /// <summary>
      /// Second card in the hand
      /// </summary>
		public Card Card2
		{
			get { return _card2; }
			set { _card2 = value; }
		}
		private Card _card3;

      /// <summary>
      /// Third card in the hand
      /// </summary>
		public Card Card3
		{
			get { return _card3; }
			set { _card3 = value; }
		}
		private Card _card4;

      /// <summary>
      /// Fourth card in the hand
      /// </summary>
		public Card Card4
		{
			get { return _card4; }
			set { _card4 = value; }
		}
		private Card _card5;

      /// <summary>
      /// Fifth card in the hand
      /// </summary>
		public Card Card5
		{
			get { return _card5; }
			set { _card5 = value; }
		}
		private int _dealCount;

      /// <summary>
      /// Current deal count
      /// </summary>
		public int DealCount
		{
			get { return _dealCount; }
			set { _dealCount = value; }
		}

		/// <summary>
		/// Called to clear the hand of cards
		/// </summary>
		public void Clear()
		{
			_card1 = null;
			_card2 = null;
			_card3 = null;
			_card4 = null;
			_card5 = null;

		}

      /// <summary>
      /// Evaluate the hand and return a payout
      /// </summary>
      /// <returns>
      /// <see cref="PayOut"/>
      /// </returns>
		public PayOut Evaluate()
		{
         PayOut po = HandEvaluator.Evaluate(this);
			return po;
		}

      /// <summary>
      /// Set the value of one of the cards in the hand
      /// </summary>
      /// <param name="CardNumber">The ordinal number of the card (1-5)</param>
      /// <param name="CardValue">Value of the card</param>
		public void SetCard(int CardNumber, byte CardValue)
		{
			if (CardNumber == 1) _card1 = new Card(CardValue);
			if (CardNumber == 2) _card2 = new Card(CardValue);
			if (CardNumber == 3) _card3 = new Card(CardValue);
			if (CardNumber == 4) _card4 = new Card(CardValue);
			if (CardNumber == 5) _card5 = new Card(CardValue);
		}

      /// <summary>
      /// Marks a card as held
      /// </summary>
      /// <param name="CardNumber">The ordinal number of the card (1-5)</param>
		public void HoldCard(int CardNumber)
		{
			if (CardNumber == 1 && _card1 != null) _card1.Held = true;
			if (CardNumber == 2 && _card2 != null) _card2.Held = true;
			if (CardNumber == 3 && _card3 != null) _card3.Held = true;
			if (CardNumber == 4 && _card4 != null) _card4.Held = true;
			if (CardNumber == 5 && _card5 != null) _card5.Held = true;
		}

      /// <summary>
      /// Marks a card as not held
      /// </summary>
      /// <param name="CardNumber">The ordinal number of the card (1-5)</param>
		public void UnHoldCard(int CardNumber)
		{
			if (CardNumber == 1 && _card1 != null) _card1.Held = false;
			if (CardNumber == 2 && _card2 != null) _card2.Held = false;
			if (CardNumber == 3 && _card3 != null) _card3.Held = false;
			if (CardNumber == 4 && _card4 != null) _card4.Held = false;
			if (CardNumber == 5 && _card5 != null) _card5.Held = false;
		}

		/// <summary>
		/// Number of coins played for this hand
		/// </summary>
		private int _coinsPlayed;

      /// <summary>
      /// Number coins played for this hand
      /// </summary>
		public int CoinsPlayed
		{
			get { return _coinsPlayed; }
			set { _coinsPlayed = value; }
		}

		private decimal _coinValue = .25M;

      /// <summary>
      /// Value of each coin played for this hand
      /// </summary>
		public decimal CoinValue
		{
			get { return _coinValue; }
			set { _coinValue = value; }
		}

      private GameTypes _gameType;

      /// <summary>
      /// Game type for this hand
      /// </summary>
      public GameTypes GameType
      {
         get { return _gameType; }
         set { _gameType = value; }
      }
	}
}
